package com.klangner.go.app;

import com.klangner.go.ab.moveselector.AllMoveSelector;
import com.klangner.go.app.rules.AlicePlayer;
import com.klangner.go.app.rules.AtariGoGame;
import com.klangner.go.app.rules.AtariGoMinMaxPlayer;
import com.klangner.go.app.rules.GoConstants;
import com.klangner.go.app.rules.GoGame;
import com.klangner.go.app.rules.HumanGoPlayer;
import com.klangner.go.app.rules.Player;
import com.klangner.go.app.strategy.AlphaBetaPruningGoStrategy;
import com.klangner.go.app.strategy.AtariGoEstimatorCho;
import com.klangner.go.app.strategy.BasicAtariGoMoveSelector;
import com.klangner.go.app.widget.GobanView;
import com.klangner.go.model.IBoard;
import com.klangner.go.model.impl.AtariGoRules;



public class GameManager {

  private Player blackPlayer;
  private Player whitePlayer;

  
  public GameManager() {
  }

  public GoGame createGame( int boardSize,
                            String blackPlayerType,
                            int blackMaxDepth,
                            String whitePlayerType,
                            int whiteMaxDepth ) {

//      log("Started GameManager.createGame: boardSize =  " +
//                         boardSize + ", blackPlayerType = " + blackPlayerType +
//                         ", blackMaxDepth = " + blackMaxDepth +
//                         ", whitePlayerType = " + whitePlayerType +
//                         ", whiteMaxDepth = " + whiteMaxDepth );

    if (blackPlayer != null) {
      blackPlayer = null;
    }
    if (whitePlayer != null) {
      whitePlayer = null;
    }

    // create the black player
    if ( blackPlayerType.equals( GoConstants.ptHumanPlayer ) ) {
        blackPlayer = createHumanPlayer( IBoard.BLACK_STONE );
//        log("Created black Human player");
    }
    else if ( blackPlayerType.equals( GoConstants.ptAlphaBetaComputerPlayer ) ) {
        blackPlayer = createAlphaBetaPlayer( IBoard.BLACK_STONE, blackMaxDepth );
//        log("Created black Alpha-Beta player");
    }
    else if (blackPlayerType.equals(GoConstants.ptAliceComputerPlayer))
      blackPlayer = createAlicePlayer(IBoard.BLACK_STONE, blackMaxDepth );

    // create the white player
    if ( whitePlayerType.equals( GoConstants.ptHumanPlayer ) ) {
      whitePlayer = createHumanPlayer( IBoard.WHITE_STONE );
//      log("Created white Human player");
    }
    else if ( whitePlayerType.equals( GoConstants.ptAlphaBetaComputerPlayer ) )
      whitePlayer = createAlphaBetaPlayer( IBoard.WHITE_STONE, whiteMaxDepth );
    else if (whitePlayerType.equals(GoConstants.ptAliceComputerPlayer))
      whitePlayer = createAlicePlayer(IBoard.WHITE_STONE, whiteMaxDepth );

    goGame = new AtariGoGame(boardSize, blackPlayer, whitePlayer);

    return goGame;
  }

  public void registerGobanView(GobanView gobanView) {
    //gobanView.removeAllMoveInputDeviceListeners();
    if (blackPlayer instanceof HumanGoPlayer)
      gobanView.addMoveInputDeviceListener((HumanGoPlayer)blackPlayer);
    if (whitePlayer instanceof HumanGoPlayer)
      gobanView.addMoveInputDeviceListener((HumanGoPlayer)whitePlayer);
  }

  public void unregisterGobanView(GobanView gobanView) {
    gobanView.removeAllMoveInputDeviceListeners();
  }

  protected HumanGoPlayer createHumanPlayer(int color) {
    return new HumanGoPlayer(color);
  }

  protected AtariGoMinMaxPlayer createAlphaBetaPlayer( int color,
                                                        int maxDepth) {
      return new AtariGoMinMaxPlayer(color,
                   new AlphaBetaPruningGoStrategy( color,
                                                   new AtariGoEstimatorCho(),
                                                   maxDepth,
                                                   new AllMoveSelector(new AtariGoRules()) ));
  }

  protected Player createAlicePlayer( int color, int maxDepth) {
    return new AlicePlayer(color);
  }

  private GoGame goGame;

}
